package com.syl.auth.authentication;

import com.syl.auth.config.SmallSecurityProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.List;

/**
 * @ClassName SmallSecurityMetadataSource
 * @Description 获取 url 对应的角色集合
 * @Author YunLong
 * @Date 2023/4/26 21:52
 */
@Slf4j
@Component
public class SmallSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    @Resource
    ResourceService resourceService;
    @Resource
    SmallSecurityProperties smallSecurityProperties;

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        // 获取url
        HttpServletRequest request = ((FilterInvocation) object).getRequest();
        String requestUrl = request.getRequestURL().toString();

        // 获取不需要登录就能访问的url
        List<String> notLoginUrls = smallSecurityProperties.getNotLoginUrls();
        // 如果是不需要登录就能访问的接口，直接放行
        if (!notLoginUrls.isEmpty() && notLoginUrls.contains(requestUrl)) {
            return null;
        }

        // 获取url对应的角色集合
        List<String> rolesByUrl = resourceService.getRolesByUrl(requestUrl);
        log.debug("url对应的角色集合:{}", rolesByUrl);
        if (CollectionUtils.isEmpty(rolesByUrl)) {
            if (smallSecurityProperties.isNoRolesPass()) {
                return null;
            }
            throw new AccessDeniedException("该接口未配置,无法访问");

        }

        return SecurityConfig.createList(rolesByUrl.toArray(new String[0]));
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return FilterInvocation.class.isAssignableFrom(aClass);
    }
}
